package com.lanzhou.yuanfen.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.lanzhou.yuanfen.config.IpAddressContext;
import com.lanzhou.yuanfen.config.Token;
import com.lanzhou.yuanfen.diary.service.IArticleService;
import com.lanzhou.yuanfen.response.ServerResponseResult;
import com.lanzhou.yuanfen.security.email.EmailService;
import com.lanzhou.yuanfen.security.session.GrantedAuthorityService;
import com.lanzhou.yuanfen.security.token.QQAuthenticationToken;
import com.lanzhou.yuanfen.sys.entity.SocialUser;
import com.lanzhou.yuanfen.sys.entity.User;
import com.lanzhou.yuanfen.sys.entity.Visitor;
import com.lanzhou.yuanfen.sys.service.ISocialUserService;
import com.lanzhou.yuanfen.sys.service.IUserService;
import com.lanzhou.yuanfen.sys.service.IVisitorService;
import com.lanzhou.yuanfen.util.RequestUtil;
import com.lanzhou.yuanfen.vo.WebSiteUV;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Map;


/**
 * @author Administrator
 */
@Controller
public class GlobalController {

    @Resource
    private IUserService userService;

    /**
     * 跳转
     *
     * @return
     */
    @RequestMapping("/loginPage")
    public String loginPage() {
        return "loginPage";
    }

    @RequestMapping("/index-cp")
    public String indexCp() {
        return "index-cp";
    }

    /**
     * 跳转
     *
     * @return
     */
    @RequestMapping("/emailLogin")
    public String emailLogin() {
        return "emailLogin";
    }

    /**
     * 跳转
     *
     * @return
     */
    @RequestMapping("/register")
    public String register() {
        return "register";
    }

    /**
     * 跳转
     *
     * @return
     */
    @RequestMapping("/fillInUser")
    public String fillInUser() {
        return "fillInUser";
    }

    /**
     * 获取用户
     *
     * @return
     */
    @ResponseBody
    @PostMapping("/getToken")
    public ServerResponseResult getToken() {
        User token = Token.getUserInfo();
        if (token == null) {
            return ServerResponseResult.fail("请先完善用户信息!!");
        }
        // 擦除关键信息
        token.setPassword(null);
        token.setBirthDate(null);
        token.setLastLoginTime(null);
        return ServerResponseResult.success(token);
    }

    @Resource
    private IVisitorService visitorService;

    @Resource
    private IpAddressContext ipAddressContext;

    /**
     * 跳转
     *
     * @return
     */
    @RequestMapping({"/index", "/", "/home"})
    public synchronized String index(HttpServletRequest request) {
        String ipAddress = RequestUtil.getIpAddress(request);
        // 访问前查看是否在系统中有这个ip
        String address = ipAddressContext.getAddress(ipAddress);
        if (address == null) {
            Visitor one = visitorService.getOne(new QueryWrapper<Visitor>()
                    .eq("ip", ipAddress).apply("to_days(visit_time) = to_days(now())"));
            if (one == null) {
                one = new Visitor();
                one.setIp(ipAddress);
            }
            one.setVisitTime(LocalDateTime.now());
            visitorService.saveOrUpdate(one);
            ipAddressContext.putAddress(ipAddress);
        }
        return "index";
    }

    /**
     * Index跳转
     *
     * @return
     */
    @RequestMapping("/index/{path}")
    public String indexPath(@PathVariable String path) {
        return "index/".concat(path);
    }

    @RequestMapping("/menu/{path}")
    public String menuPath(@PathVariable String path) {
        return "menu/".concat(path);
    }

    @RequestMapping("/sys/{path}")
    public String sysPath(@PathVariable String path) {
        return "sys/".concat(path);
    }

    @RequestMapping("/tool/{path}")
    public String toolPath(@PathVariable String path) {
        return "tool/".concat(path);
    }

    @RequestMapping("/anonymous/{path}")
    public String anonymousPath(@PathVariable String path) {
        return "anonymous/".concat(path);
    }

    @Resource
    private PasswordEncoder passwordEncoder;
    @Resource
    private ISocialUserService socialUserService;

    @Resource
    private GrantedAuthorityService grantedAuthorityService;

    /**
     * 注册用户(加个锁)
     *
     * @return
     */
    @ResponseBody
    @RequestMapping("/registerUser")
    public synchronized ServerResponseResult registerUser(UserDto userDto) {
        Object result = obtainUser(userDto);
        if (result instanceof String) {
            return ServerResponseResult.fail(result.toString());
        }
        User user = (User) result;
        userService.registerUser(user);
        return ServerResponseResult.success();
    }

    @Resource
    private IArticleService iArticleService;

    /**
     * 注册用户(加个锁)
     *
     * @return
     */
    @ResponseBody
    @PostMapping("getYFInfo")
    public synchronized ServerResponseResult getYFInfo(@RequestParam("userKey") String userKey) {
        Map<String, Long> yfInfo = iArticleService.getYFInfoByUserKey(userKey);
        // TODO 还有YF币呢
        return ServerResponseResult.success(yfInfo);
    }


    /**
     * 获取网络UV视图
     *
     * @return
     */
    @ResponseBody
    @RequestMapping("/getWebUV")
    public ServerResponseResult getWebUV() {
        WebSiteUV uv = visitorService.recentWeekUV();
        return ServerResponseResult.success(uv);
    }

    /**
     * 获取网络UV视图
     *
     * @return
     */
    @ResponseBody
    @RequestMapping("/thumbWeb")
    public ServerResponseResult thumbWeb(HttpServletRequest request) {
        String ipAddress = RequestUtil.getIpAddress(request);
        Visitor one = visitorService.getOne(new QueryWrapper<Visitor>()
                .eq("ip", ipAddress).apply("to_days(visit_time) = to_days(now())"));
        if (one.getIsThumb()) {
            return ServerResponseResult.fail("您当前已经点赞过了哦");
        } else {
            visitorService.update(new UpdateWrapper<Visitor>().eq("id", one.getId()).set("is_thumb", true));
        }
        return ServerResponseResult.success();
    }


    /**
     * 注册用户(加个锁): 之后刷新权限
     *
     * @return
     */
    @RequestMapping("/registerFillUser")
    @ResponseBody
    public synchronized ServerResponseResult registerFillUser(HttpServletRequest request, UserDto userDto) {
        Object result = obtainUser(userDto);
        if (result instanceof String) {
            return ServerResponseResult.fail(result.toString());
        }
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication instanceof QQAuthenticationToken) {
            User user = (User) result;
            String openId = ((QQAuthenticationToken) authentication).getOpenId();
            userService.registerFillUser(user, openId);
            grantedAuthorityService.reloadUserAuthority(request.getSession(), user.getUserKey());
        }
        return ServerResponseResult.success();
    }

    /**
     * 注册用户(加个锁): 之后刷新权限
     *
     * @return
     */
    @PostMapping("/updateUserInfo")
    @ResponseBody
    public synchronized ServerResponseResult updateUserInfo(HttpServletRequest request, UserDto userDto) {
        User user = userDto.buildUser();
        userService.updateById(user);
        grantedAuthorityService.reloadUserAuthority(request.getSession(), user.getUserKey());
        return ServerResponseResult.success();
    }

    /**
     * 推断用户, 感受是否是错误信息
     *
     * @param userDto
     * @return
     */
    private Object obtainUser(UserDto userDto) {
        User nameExist = userService.getOne(new QueryWrapper<User>().eq("username", userDto.username));
        if (nameExist != null) {
            return "您输入的用户名已存在 !";
        }
        User emailExist = userService.getOne(new QueryWrapper<User>().eq("email", userDto.email));
        if (emailExist != null) {
            return "当前邮箱已经注册用户!";
        }
        User user = userDto.buildUser();
        user.setPassword(passwordEncoder.encode(userDto.password));
        return user;
    }


    /**
     * 绑定用户: 之后刷新权限
     *
     * @return
     */
    @PostMapping("/bandingUser")
    public ServerResponseResult bandingUser(HttpServletRequest request,
                                            @RequestParam("username") String username,
                                            @RequestParam("password") String password) {
        User user = userService.getOne(new QueryWrapper<User>().eq("username", username));
        if (user == null) {
            return ServerResponseResult.fail("您输入的用户或密码错误");
        } else {
            String pwd = user.getPassword();
            boolean matches = passwordEncoder.matches(password, pwd);
            if (!matches) {
                return ServerResponseResult.fail("您输入的用户或密码错误");
            } else {
                Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
                if (authentication instanceof QQAuthenticationToken) {
                    String openId = ((QQAuthenticationToken) authentication).getOpenId();
                    boolean update = socialUserService.update(new UpdateWrapper<SocialUser>()
                            .eq("open_id", openId)
                            .set("user_key", user.getUserKey()));
                    if (!update) {
                        return ServerResponseResult.fail("绑定失败, 请稍后重试");
                    } else {
                        grantedAuthorityService.reloadUserAuthority(request.getSession(), user.getUserKey());
                    }
                }
            }
        }
        return ServerResponseResult.success();
    }


    @Resource
    private EmailService emailService;

    /**
     * 注册用户(加个锁)
     *
     * @return
     */
    @RequestMapping("/sendEmail")
    @ResponseBody
    public synchronized ServerResponseResult sendEmail(@RequestParam("email") String email) {
        User nameExist = userService.getOne(new QueryWrapper<User>().eq("email", email));
        if (nameExist == null) {
            return ServerResponseResult.fail("您输入的用户信息错误, 请重新输入 !");
        }
        String emailCode = generateEmailCode();
        String text = "尊敬的" + nameExist.getUsername() + " : 您此次登入的验证码为: " + emailCode;
        emailService.sendSimpleMail("【猿粪】关于猿粪网此次登入的验证码通知", text, nameExist.getEmail());
        userService.update(new UpdateWrapper<User>().eq("user_key", nameExist.getUserKey()).set("eml_code", emailCode));
        return ServerResponseResult.success();
    }

    /**
     * 生成Email登入验证码(6位数)
     *
     * @return
     */
    private String generateEmailCode() {
        int i = (int) ((Math.random() * 9 + 1) * 100000);
        return "" + i;
    }


    @Data
    @EqualsAndHashCode(callSuper = false)
    static class UserDto {
        private Long userKey;
        private String username;
        private String password;
        private String email;
        private String gender;
        private String avatar;
        private String nickName;
        private Integer age;
        private String declarate;

        private User buildUser() {
            User user = new User();
            user.setUserKey(userKey);
            user.setUsername(username);
            user.setEmail(email);
            user.setGender(gender);
            user.setAvatar(avatar);
            user.setNickName(nickName);
            user.setAge(age);
            user.setDeclarate(declarate);
            return user;
        }
    }


}
